import axios from "axios";

import router from "../router";

import { VERIFY_FAILED_COMMAND, CANCEL_MESSAGE } from "@/config";

/**
 * @Author: GuoXinyuan
 * @Date: 2021/5/28
 *
 * httpRequest封装 主要功能如下：
 * 权限验证：
 *  post/get 当收到 response 会调用 checkVerify()方法检查登录状态，失败则推回主页
 * 判断逻辑封装：
 *  对于一般 post/get请求(返回ResponseVO)不需要进行网络成功但逻辑失败的情况
 *  success(var)回调参数var为 ResponseVO中content内容
 *  error(var)回调参数var为 ResponseVO中message内容
 *  更复杂请求需要封装其他函数
 */

axios.defaults.withCredentials = true; //设置请求头携带cookie

// const defaultPostContentType = "application/json";
const defaultPostContentType = "application/x-www-form-urlencoded";

import global from "@/global";

/**
 * 验证登录状态 未验证成功则退回主页
 * @param errorMessage
 * @param error
 */
const checkVerify = function(errorMessage, error) {
  if (errorMessage !== VERIFY_FAILED_COMMAND) {
    error(errorMessage);
  } else {
    window.localStorage.clear();
    if (window.location.pathname === "/") {
      global.clearAll(); //开发阶段在重启后台后发送请求需要清空用户数据
      error("尚未登入");
    } else {
      router.replace({ path: "/" }).then(() => {
        global.clearAll(); //开发阶段在重启后台后发送请求需要清空用户数据
        error("尚未登入");
      });
    }

  }
};

/**
 * 封装post请求
 * @param path 请求路径
 * @param data 请求数据
 * @param success 成功回调(只是网络成功;可能是后台逻辑失败,这时也会调用error)
 * @param error 失败回调
 * @param final 请求完成后回调(不论成功失败都要执行)
 * @param config
 */
export const post = function(path, data, success, error, final, config) {
  if (typeof config !== "object")
    config = { header: { "content-type": defaultPostContentType } };

  //用于终止请求
  let source = axios.CancelToken.source();
  config.cancelToken = source.token;

  axios
    .post(path, data, config)
    .then(res => {
      console.log("post", res);
      if (res.data.success) success(res.data.content);
      else checkVerify(res.data.message, error);
    })
    .catch(err => {
      if (err.message !== CANCEL_MESSAGE) error(err);
    })
    .finally(() => {
      if (typeof final === "function") final();
    });

  return source;
};

/**
 * 封装get请求
 * @param path
 * @param success 成功回调(只是网络成功;可能是后台逻辑失败,这时也会调用error)
 * @param error 失败回调
 * @param final 请求完成后回调(不论成功失败都要执行)
 */
export const get = function(path, success, error, final) {
  //用于终止请求
  let source = axios.CancelToken.source();
  let config = {
    cancelToken: source.token
  };

  axios
    .get(path, config)
    .then(res => {
      if (res.data.success) {
        success(res.data.content);
      } else checkVerify(res.data.message, error);
    })
    .catch(err => {
      if (err.message !== CANCEL_MESSAGE) error(err);
    })
    .finally(() => {
      if (typeof final === "function") final();
    });

  return source;
};

/**
 * 获取二进制流 post
 * @param path
 * @param data
 * @param success
 * @param error
 * @param final
 * @param config
 */
export const postForFile = function(path, data, success, error, final, config) {
  if (typeof config !== "object")
    config = {
      header: { "content-type": defaultPostContentType, responseType: "blob" }
    };
  axios
    .post(path, data, config)
    .then(res => {
      if (res.data.message) {
        checkVerify(res.data.message, error);
      } else {
        success(res.data);
      }
    })
    .catch(err => {
      error(err);
    })
    .finally(() => {
      if (typeof final === "function") final();
    });
};
